package com.iot.dw.netty;

import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

/**
 * Socket拦截器，用于处理客户端的行为
 *
 * @author Gjing
 **/
@Slf4j
public class SocketHandler extends ChannelInboundHandlerAdapter {
    public static final AttributeKey<String> NETTY_CHANNEL_KEY = AttributeKey.valueOf("netty.channel");

    public static final ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 读取到客户端发来的消息
     *
     * @param ctx ChannelHandlerContext
     * @param msg msg
     * @throws Exception e
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        // 由于我们配置的是 字节数组 编解码器，所以这里取到的用户发来的数据是 byte数组
        var m = (GbxfMessage) msg;
        if(m.isSuccess()){
            var attr = ctx.channel().attr(NETTY_CHANNEL_KEY);
            var id=attr.get();
            if(StringUtils.hasText(id)){
                log.info("old id:{}",id);
            }
            attr.set(m.getId() );
            log.info("接收成功 IP:{}   id:{} rev:{}  ",
                    ctx.channel().remoteAddress(),
                     m.getId(),m.getHexStr() );
        }else{
            log.error("接收失败 IP:{}   rev:{}  ",
                    ctx.channel().remoteAddress(),  m.getHexStr() );
        }

        ctx.channel().writeAndFlush(m);
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        log.info("新的客户端链接：" + ctx.channel().id().asShortText());
        clients.add(ctx.channel());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        clients.remove(ctx.channel());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.channel().close();
        clients.remove(ctx.channel());
    }
}
